package com.ts.api.module.api.controller;

import com.gitee.apanlh.annotation.viewresolver.RequestParamVo;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.web.model.vo.RequestVO;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.common.constant.api.ApiProviderEnum;
import com.ts.api.common.constant.api.ApiServiceCodeEnum;
import com.ts.api.common.context.ApiContext;
import com.ts.api.exp.ApiMsgException;
import com.ts.api.module.api.convert.receive.handler.DelegatingApiReceivePhoneMaskConvertHandler;
import com.ts.api.module.api.convert.receive.handler.DelegatingApiReceivePhoneMd5ConvertHandler;
import com.ts.api.module.api.entity.bo.ApiCustomPushBO;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.api.service.ApiReceiveCustomPushService;
import com.ts.api.module.api.service.ApiReceivePreMd5Service;
import com.ts.api.module.api.service.ApiReceiveSpecialService;
import com.ts.api.module.api.service.ApiReceiveV2Service;
import com.ts.api.module.api.service.ApiReceiveV3Service;
import com.ts.api.module.api.service.ApiRequestValidateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 *  API量流程-被动接收
 *
 *  @author Pan
 */
@RestController
@RequestMapping("/data/api/receive")
public class ApiMsgReceiveController {

    @Autowired
    private DelegatingApiReceivePhoneMd5ConvertHandler delegatingApiReceivePhoneMd5ConvertHandler;
    @Autowired
    private DelegatingApiReceivePhoneMaskConvertHandler delegatingApiReceivePhoneMaskConvertHandler;
    @Autowired
    private ApiReceiveCustomPushService apiReceiveCustomPushService;
    @Autowired
    private ApiRequestValidateService apiRequestValidateService;
    @Autowired
    private ApiReceiveV2Service apiReceiveV2Service;
    @Autowired
    private ApiReceiveV3Service apiReceiveV3Service;
    @Autowired
    private ApiReceiveSpecialService apiReceiveSpecialService;
    @Autowired
    private ApiReceivePreMd5Service apiReceivePreMd5Service;

    /**
     *  撞库接收-V2
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v2/dataExchange/{apiClientId}")
    public Map<String, Object> dataExchangeV2(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveV2Service.dataExchange(apiKeyPO, requestVO);
    }

    /**
     *  进件接收-V2
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v2/apply/{apiClientId}")
    public Map<String, Object> applyV2(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveV2Service.apply(apiKeyPO, requestVO);
    }

    /**
     *  半流程-通用接口-v2（撞库进件合并接口）
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v2/full/{apiClientId}")
    public Map<String, Object> fullV2(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  解析参数获取撞库还是进件
        delegatingApiReceivePhoneMd5ConvertHandler.requireParam(requestVO);
        String serviceCode = ApiContext.SERVICE_CODE.get();

        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        //  撞库
        if (Eq.enums(ApiServiceCodeEnum.A0001, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveV2Service.dataExchange(apiKeyPO, requestVO);
        }
        //  进件
        if (Eq.enums(ApiServiceCodeEnum.A0002, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveV2Service.apply(apiKeyPO, requestVO);
        }
        throw new ApiMsgException(ApiEnum.API_NULL_FAIL.format("业务编码", "不可为null"));
    }

    /**
     *  半流程V2-进件申请授权接口
     *  接入对方回调授权页面-下游半流程回调通知
     *
     *  @param  productId       主体id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v2/callNotice/{productId}")
    public Map<String, Object> applyCallNoticeV2(@RequestParamVo RequestVO requestVO, @PathVariable Long productId) {
        return apiReceiveV2Service.applyCallbackNotice(productId, requestVO);
    }

    /**
     *  全流程撞库-V3
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v3/dataExchange/{apiClientId}")
    public Map<String, Object> dataExchangeV3(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveV3Service.dataExchange(apiKeyPO, requestVO);
    }

    /**
     *  全流程进件-V3
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v3/apply/{apiClientId}")
    public Map<String, Object> applyV3(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveV3Service.apply(apiKeyPO, requestVO);
    }

    /**
     *  全流程通用接口-V3（撞库进件合并接口）
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v3/full/{apiClientId}")
    public Map<String, Object> fullV3(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  解析参数获取撞库还是进件
        delegatingApiReceivePhoneMd5ConvertHandler.requireParam(requestVO);
        String serviceCode = ApiContext.SERVICE_CODE.get();

        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        //  撞库
        if (Eq.enums(ApiServiceCodeEnum.A0001, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveV3Service.dataExchange(apiKeyPO, requestVO);
        }
        //  进件
        if (Eq.enums(ApiServiceCodeEnum.A0002, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveV3Service.apply(apiKeyPO, requestVO);
        }
        throw new ApiMsgException(ApiEnum.API_NULL_FAIL.format("业务编码", "不可为null"));
    }

    /**
     *  全流程撞库-手机号掩码8位模式
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v3/dataExchange/phoneMask{maskLen}/{apiClientId}")
    public Map<String, Object> dataExchangePhoneMaskV3(@PathVariable String apiClientId, @PathVariable Integer maskLen, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveV3Service.dataExchangePhoneMask(apiKeyPO, requestVO, maskLen);
    }

    /**
     *  全流程进件-手机号掩码8位模式
     *
     *  @param  apiClientId     客户端id
     *  @param  maskLen         掩码长度
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v3/apply/phoneMask{maskLen}/{apiClientId}")
    public Map<String, Object> applyPhoneMaskV3(@PathVariable String apiClientId, @PathVariable Integer maskLen, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveV3Service.applyPhoneMask(apiKeyPO, requestVO, maskLen);
    }

    /**
     *  全流程通用接口-V3（撞库进件合并接口）
     *
     *  @param  apiClientId     客户端id
     *  @param  maskLen         掩码长度
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/v3/full/phoneMask{maskLen}/{apiClientId}")
    public Map<String, Object> fullV3(@PathVariable String apiClientId, @PathVariable Integer maskLen, @RequestParamVo RequestVO requestVO) {
        //  解析参数获取撞库还是进件
        delegatingApiReceivePhoneMaskConvertHandler.requireParam(requestVO);
        String serviceCode = ApiContext.SERVICE_CODE.get();

        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        //  撞库
        if (Eq.enums(ApiServiceCodeEnum.A0001, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveV3Service.dataExchangePhoneMask(apiKeyPO, requestVO, maskLen);
        }
        //  进件
        if (Eq.enums(ApiServiceCodeEnum.A0002, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveV3Service.applyPhoneMask(apiKeyPO, requestVO, maskLen);
        }
        throw new ApiMsgException(ApiEnum.API_NULL_FAIL.format("业务编码", "不可为null"));
    }

    /**
     *  特殊计划-100%撞库接收
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/special/dataExchange/{apiClientId}")
    public Map<String, Object> dataExchangeSpecial(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveSpecialService.dataExchange(apiKeyPO, requestVO);
    }

    /**
     *  特殊计划-进件接收-100%进件
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/special/apply/{apiClientId}")
    public Map<String, Object> applySpecial(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceiveSpecialService.apply(apiKeyPO, requestVO);
    }

    /**
     *  自定义全流程-撞库
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/custom/dataExchange/{apiClientId}/{productId}")
    public Map<String, Object> dataExchange(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO, @PathVariable Long productId) {
        Assert.isNotNullThrows(apiClientId, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("客户端id", "不可为null")));
        Assert.isNotNullThrows(productId, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("机构id", "不可为null")));

        //  1.验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());
        ApiCustomPushBO apiCustomPushBO = ApiCustomPushBO.create(apiKeyPO, productId, requestVO);
        //  2.撞库
        return apiReceiveCustomPushService.dataExchange(apiCustomPushBO);
    }

    /**
     *  全流程-进件
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/custom/apply/{apiClientId}/{productId}")
    public Map<String, Object> applyV3(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO, @PathVariable Long productId) {
        Assert.isNotNullThrows(apiClientId, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("客户端id", "不可为null")));
        Assert.isNotNullThrows(productId, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("机构id", "不可为null")));

        //  1.验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        //  2.进件流程
        ApiCustomPushBO apiCustomPushBO = ApiCustomPushBO.create(apiKeyPO, productId, requestVO);
        return apiReceiveCustomPushService.apply(apiCustomPushBO);
    }

    /**
     *  全流程-撞库/进件合并接口
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/custom/full/{apiClientId}/{productId}")
    public Map<String, Object> customFull(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO, @PathVariable Long productId) {
        Assert.isNotNullThrows(apiClientId, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("客户端id", "不可为null")));
        Assert.isNotNullThrows(productId, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("机构id", "不可为null")));

        //  解析参数获取撞库还是进件
        delegatingApiReceivePhoneMd5ConvertHandler.requireParam(requestVO);

        //  1.验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        //  业务推送实体
        ApiCustomPushBO apiCustomPushBO = ApiCustomPushBO.create(apiKeyPO, productId, requestVO);
        String serviceCode = ApiContext.SERVICE_CODE.get();

        //  撞库
        if (Eq.enums(ApiServiceCodeEnum.A0001, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveCustomPushService.dataExchange(apiCustomPushBO);
        }

        //  进件
        if (Eq.enums(ApiServiceCodeEnum.A0002, ApiServiceCodeEnum.get(serviceCode))) {
            return apiReceiveCustomPushService.apply(apiCustomPushBO);
        }
        throw new ApiMsgException(ApiEnum.API_NULL_FAIL.format("业务编码", "不可为null"));
    }

    /**
     *  前置是否查询库存在
     *
     *  @param  apiClientId     客户端id
     *  @param  requestVO       请求实体
     *  @return Map
     */
    @PostMapping("/exist/md5/{apiClientId}")
    public Map<String, Object> existMd5(@PathVariable String apiClientId, @RequestParamVo RequestVO requestVO) {
        //  验证客户端
        ApiKeyPO apiKeyPO = apiRequestValidateService.validClient(apiClientId);
        apiRequestValidateService.validAccess(apiKeyPO, ApiProviderEnum.WE.getType());

        return apiReceivePreMd5Service.dataExchange(apiKeyPO, requestVO);
    }
}
